package com.cee.admin.config.shiro;

import com.cee.admin.config.shiro.jwt.JwtToken;
import com.cee.admin.config.shiro.jwt.TokenService;
import com.cee.domain.modules.sys.entity.Role;
import com.cee.domain.modules.sys.entity.User;
import com.cee.ds.common.utils.BasePrincipalUtils;
import com.cee.ds.modules.sys.service.IMenuService;
import com.cee.ds.modules.sys.service.IUserRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.util.Objects;

import static com.cee.common.web.result.ResultCode.USER_ACCOUNT_DISABLE;

@Slf4j
public class ShiroRealm extends AuthorizingRealm {


    @Autowired
    private TokenService tokenService;

    @Autowired
    private IMenuService iMenuService;

    @Autowired
    private IUserRoleService userRoleService;

    /**
     * 建议重写
     *
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User) principalCollection.getPrimaryPrincipal();
        principalCollection.asList();
        if (ObjectUtils.isEmpty(user) || ObjectUtils.isEmpty(user.getId())) {
            return null;
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Role role = userRoleService.getEnableRoleByUserId(user.getId());
        if (Objects.nonNull(role)) {
            info.setStringPermissions(iMenuService.queryPermSetByRoleId(role.getId()));
        }
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        log.trace("===============Shiro身份认证开始============doGetAuthenticationInfo==========");
        Object token = auth.getCredentials();
        if (token == null) {
            throw new ExpiredCredentialsException("凭证为空!");
        }
        // 校验token有效性
        User user = tokenService.verificationToken((String) token);
        // 判断是否是被禁用的账号
        if (BasePrincipalUtils.isDisable(user.getStatus())) {
            throw new DisabledAccountException(USER_ACCOUNT_DISABLE.getMsg());
        }
        return new SimpleAuthenticationInfo(user, token, getName());
    }
}
